import numpy as np
import pandas as pd
import matplotlib
import functions as f
from itertools import combinations

matplotlib.rc("font", family='Microsoft YaHei')
# 读取数据
history_data = pd.read_csv('HistoryFIFAMatch.csv')

# 选择特征和标签
features = ['home_FIFA_Ranking', 'away_FIFA_Ranking',
            'home_winrate_im', 'away_winrate_im',
            'home_winrate_wcm', 'away_winrate_wcm',
            'home_team_win_rate', 'away_team_win_rate'
            ]
history_X = history_data[features].values
history_y = history_data['result_n'].values  # 1:主队胜, 0:客队胜, -1:平局
history_y = np.where(history_y == -1, 2, history_y)  # 将平局(-1)转换为2

X_scaled, X_mean, X_std = f.manual_standardize(history_X)

'''
由于平局数量较少,在选取测试集训练集比例时,
--->
使用分层抽样,过采样的方法
'''

# X_train, X_test, y_train, y_test = manual_train_test_split(X_scaled, history_y, test_size=0.35, random_state=50)
# 0.35 50


X_train, X_test, y_train, y_test = f.manual_stratified_split(X_scaled, history_y, test_size=0.35, random_state=40)
X_train_balanced, y_train_balanced = f.smart_draw_oversampling(X_train, y_train, 0.3, 42)
# X_train_balanced, y_train_balanced = f.oversample_minority_class(X_train, y_train)
# 检查分层抽样结果
print("原始分布:")
f.check_stratification(y_train, y_test, ['客队胜', '主队胜', '平局'])

# X_train_balanced, y_train_balanced = f.oversample_minority_class(X_train, y_train, 80, 50)

print("\n过采样后的训练集分布:")
unique, o_counts = np.unique(y_train_balanced, return_counts=True)
for cls, o_count in zip(['客队胜', '主队胜', '平局'], o_counts):
    print(f"{cls}: {o_count} ({o_count / len(y_train_balanced):.1%})")

# 初始化代价敏感模型
cost_matrix = np.array([
    [0, 1, 1],
    [1, 0, 1],
    [5, 5, 0]  # 提高平局误判代价
])

# 高斯概率分布朴素贝叶斯分类器
model = f.ManualGaussianNB()
model.fit(X_train_balanced, y_train_balanced)

# 预测
history_y_pred = model.predict(X_test)

# 打印评估结果
print("Accuracy:", f.manual_accuracy(y_test, history_y_pred))
print("\nConfusion Matrix:")
print(f.manual_confusion_matrix(y_test, history_y_pred, classes=[0, 1, 2]))

print("\nClassification Report:")
assess_report = f.manual_classification_report(y_test, history_y_pred, classes=[0, 1, 2],
                                               class_names=['客队胜', '主队胜', '平局'])
for class_name, metrics in assess_report.items():
    print(f"{class_name}:")
    print(f"  Precision: {metrics['precision']:.2f}")
    print(f"  Recall: {metrics['recall']:.2f}")
    print(f"  F1-score: {metrics['f1-score']:.2f}")
    print(f"  Support: {metrics['support']}")

assess_cm = f.manual_confusion_matrix(y_test, history_y_pred, classes=[0, 1, 2])

# 绘制混淆矩阵
f.plot_confusion_matrix(assess_cm, class_names=['客队胜利', '主队胜利', '平局'], title='世界杯比赛结果预测混淆矩阵')

# 小组赛预测
QatarMatch_file_path = "C://Users//54114//OneDrive//Desktop//FIFAPrediction//KeyCode//group_match_analysis.csv"
GroupMatch = pd.read_csv(QatarMatch_file_path)
# 存储最终结果
qualified_teams = {}
group_standings = {}

for group in sorted(GroupMatch['Group'].unique()):
    group_teams = GroupMatch[GroupMatch['Group'] == group]

    # 初始化积分榜
    standings = {row['Team']: {
        'points': 0,
        'qualify16': row['qualify16'],
        'goals_for': 0,
        'goals_against': 0
    } for _, row in group_teams.iterrows()}

    # 模拟所有比赛
    for home, away in combinations(group_teams['Team'], 2):
        home_stats = group_teams[group_teams['Team'] == home].iloc[0]
        away_stats = group_teams[group_teams['Team'] == away].iloc[0]

        result = f.predict_match(home_stats, away_stats, X_mean, X_std, model)

        # 模拟进球数
        home_goals = np.random.poisson(1.5 if result == 1 else 0.8)
        away_goals = np.random.poisson(1.5 if result == 0 else 0.8)

        # 更新积分和净胜球
        if result == 1:  # 主队胜
            standings[home]['points'] += 3
        elif result == 0:  # 客队胜
            standings[away]['points'] += 3
        else:  # 平局
            standings[home]['points'] += 1
            standings[away]['points'] += 1

        standings[home]['goals_for'] += home_goals
        standings[home]['goals_against'] += away_goals
        standings[away]['goals_for'] += away_goals
        standings[away]['goals_against'] += home_goals

    # 计算净胜球
    for team in standings:
        standings[team]['goal_diff'] = standings[team]['goals_for'] - standings[team]['goals_against']

    # 排序：积分 > 净胜球 > 综合胜率
    sorted_teams = sorted(standings.items(),
                          key=lambda x: (-x[1]['points'],
                                        -x[1]['goal_diff'],
                                         -x[1]['qualify16']))

    # 存储小组赛果
    group_standings[group] = {
        team: {**stats, 'position': i + 1}
        for i, (team, stats) in enumerate(sorted_teams)
    }

    # 存储出线队伍
    qualified_teams[f"{group}1"] = sorted_teams[0][0]
    qualified_teams[f"{group}2"] = sorted_teams[1][0]

# 打印结果
print("各小组出线队伍:")
print("-" * 30)
for code, team in qualified_teams.items():
    print(f"{code}: {team}")

print("\n各小组详细排名:")
for group, standings in group_standings.items():
    print(f"\nGroup {group}:")
    print("-" * 20)
    for team, stats in sorted(standings.items(), key=lambda x: x[1]['position']):
        print(f"{stats['position']}. {team}: {stats['points']}分 "
              f"(净胜球: {stats['goal_diff']})")  # , 综合胜率: {stats['qualify16']:.3f}
print(qualified_teams)
# 1/8决赛(16强)
round_of_16 = [
    ("A1", "B2"), ("B1", "A2"),
    ("C1", "D2"), ("D1", "C2"),
    ("E1", "F2"), ("F1", "E2"),
    ("G1", "H2"), ("H1", "G2")
]
round_of_16_winners = f.KnockoutMatchPredict(GroupMatch, round_of_16, qualified_teams,
                                             "1/8决赛", X_mean, X_std, model)

# 1/4决赛(8强)
round_of_8 = [
    ('W1', 'W3'), ('W2', 'W4'),
    ('W5', 'W7'), ('W6', 'W8')
]
round_of_8_winners = f.KnockoutMatchPredict(GroupMatch, round_of_8, qualified_teams, "1/4决赛", X_mean, X_std, model)

# 半决赛(4强)
round_of_semi = [
    ('W1', 'W3'), ('W2', 'W4')
]
round_of_semi_winners = f.KnockoutMatchPredict(GroupMatch, round_of_semi, qualified_teams, "半决赛", X_mean, X_std,
                                               model)

# 决赛
round_of_final = [('W1', 'W2')]
final_winner = f.KnockoutMatchPredict(GroupMatch, round_of_final, qualified_teams, "决赛", X_mean, X_std, model)
